#define NOMINMAX
#include "NatDebtFutureToolsParam.h"
#include <bondlib/BondContainer.h>
#include <bondlib/SSVContainer.h>
#include <bondlib/BondCDCPriceInfo.h>
#include <core/time/date.h>

void CNatIRRSingle::Print()
{
	std::string strTemp;
	strTemp = qb::base::string_format("---ToolsParam--print---  bondCode:%s bondKey:%s ofrPrc:%s ofr:%.3f ofrClean:%.3f ofrIrr:%.3f ofrBas %.3f BidPrc:%s bid:%.3f bidClean:%.3f bidIrr:%.3f bidBas %.3f DealPrc:%s Deal:%.3f DealClean:%.3f dealIrr:%.3f DealBas %.3f\r\n",
		m_strCombCode.c_str(), m_strCombKey.c_str(), m_PrcOfr.m_cPrice, m_PrcOfr.m_dbYTM, m_PrcOfr.m_dbCleanPrice, m_PrcOfr.m_dbIRR, m_PrcOfr.m_dbBasis,
		m_PrcBid.m_cPrice, m_PrcBid.m_dbYTM, m_PrcBid.m_dbCleanPrice, m_PrcBid.m_dbIRR, m_PrcBid.m_dbBasis,
		m_PrcDeal.m_cPrice, m_PrcDeal.m_dbYTM, m_PrcDeal.m_dbCleanPrice, m_PrcDeal.m_dbIRR, m_PrcDeal.m_dbBasis);
	//OutputDebugString(strTemp.t());
}
void CNatIRRSingle::Copy(const CNatIRRSingle& natSgl){

	m_strCombKey = natSgl.m_strCombKey;
	m_strCombCode = natSgl.m_strCombCode;
	m_dbConvertFactor = natSgl.m_dbConvertFactor;
	m_unDelivery_Date = natSgl.m_unDelivery_Date;
	m_nBrokerID = natSgl.m_nBrokerID;
	m_PrcBid = natSgl.m_PrcBid;
	m_PrcOfr = natSgl.m_PrcOfr;
	m_PrcDeal = natSgl.m_PrcDeal;
	m_PrcEst = natSgl.m_PrcEst;
	m_PrcMid = natSgl.m_PrcMid;
	m_PrcLastestDeal = natSgl.m_PrcLastestDeal;
	m_nBondIndex = natSgl.m_nBondIndex;
	m_dbAccruedAmount = natSgl.m_dbAccruedAmount;
	m_dbCashPrice = natSgl.m_dbCashPrice;
	m_tMaxTime = std::max(m_PrcBid.m_tTime,m_PrcOfr.m_tTime);
}
//////////现券计算参数
CNatBondFutureToolsParam::CNatBondFutureToolsParam()
{
}

CNatBondFutureToolsParam::~CNatBondFutureToolsParam()
{	
}

void CNatBondFutureToolsParam::InitialTFBroker(std::vector<CBrokerUnit>& broker , std::vector<CFutureInfo>& tf)
{
	m_vctTF.clear();
	int nSz = tf.size();
	for(int nL = 0 ; nL < nSz ; nL ++){
		CNatToolsTFP toolTf;
		toolTf.InitialTF(tf[nL].m_TF_ID,broker);
		m_vctTF.push_back(toolTf);
	}
	//for(vector<CFutureInfo>::const_iterator itrTF = tf.begin(); itrTF != tf.end(); ITR ++)
}

void CNatBondFutureToolsParam::Clear()
{
	m_vctTF.clear();
}

const CNatToolsTFP* CNatBondFutureToolsParam::GetTFParamFromID(const std::string tfID)
{
	for (vector<CNatToolsTFP>::const_iterator itr = m_vctTF.begin(); itr != m_vctTF.end(); itr++){
		if (itr->m_strTFId == tfID){
			return &(*itr);
		}
	}
	return nullptr;
}

void CNatToolsBrokP::InsertBond(const xQBRefBond_c& refbond){//插入一只债券
	CNatIRRSingle bondP;
	std::string strEst = "";
	bondP.m_PrcEst.m_tTime = GetBondEstTime(refbond.m_Bond_Key, strEst);
	if(!strEst.empty()){
		FIELDCOPY(bondP.m_PrcEst.m_cPrice, strEst.c_str());
	}
	bondP.m_dbConvertFactor = refbond.m_Conversion_Factor;
	if (CBrokerList::IsValidBroker(m_nBrokerID) || m_nBrokerID == NEW_DETAIL_CFETS_BROKER) {
		int bondIndex = CBondContainer::instance().GetBondIndex(refbond.m_Bond_Key, CBondContainer::lmCIB);
		if (CBondContainer::instance().IsValidIndex(bondIndex))
		{
			const CBondInfo& info = CBondContainer::instance().ElementAtR(bondIndex);
			bondP.m_nBondIndex = bondIndex;
			bondP.m_strCombKey = qb::base::string_format("%s", info.GetCombBondKey());
			bondP.m_strCombCode = qb::base::string_format("%s", info.GetCombBondCode());
			m_mapBond.insert(std::pair<std::string, CNatIRRSingle>(bondP.m_strCombKey, bondP));
		}
	}
	else if (m_nBrokerID == NEW_DETAIL_EXCHANGE_BROKER) {
		int bondIndex = CBondContainer::instance().GetBondIndex(refbond.m_Bond_Key, CBondContainer::lmSSE);
		if (CBondContainer::instance().IsValidIndex(bondIndex))
		{
			const CBondInfo& info = CBondContainer::instance().ElementAtR(bondIndex);
			bondP.m_nBondIndex = bondIndex;
			bondP.m_strCombKey = qb::base::string_format("%s", info.GetCombBondKey());
			bondP.m_strCombCode = qb::base::string_format("%s", info.GetCombBondCode());
			m_mapBond.insert(std::pair<std::string, CNatIRRSingle>(bondP.m_strCombKey, bondP));
		}

		bondIndex = CBondContainer::instance().GetBondIndex(refbond.m_Bond_Key, CBondContainer::lmSZE);
		if (CBondContainer::instance().IsValidIndex(bondIndex))
		{
			const CBondInfo& info = CBondContainer::instance().ElementAtR(bondIndex);
			bondP.m_nBondIndex = bondIndex;
			bondP.m_strCombKey = qb::base::string_format("%s", info.GetCombBondKey());
			bondP.m_strCombCode = qb::base::string_format("%s", info.GetCombBondCode());
			m_mapBond.insert(std::pair<std::string, CNatIRRSingle>(bondP.m_strCombKey, bondP));
		}
	}
}

bool CNatToolsBrokP::InsertCumstomBond(const char* cBondKey , const char* cListMarket) 
{
	CBondInfo info;
	CNatIRRSingle bondP;
	std::string strEst = "";
	bondP.m_PrcEst.m_tTime = GetBondEstTime(cBondKey, strEst);
	if(!strEst.empty()){
		FIELDCOPY(bondP.m_PrcEst.m_cPrice, strEst.c_str());
	}
	int bondIndex = CBondContainer::instance().GetBondIndex(cBondKey, cListMarket);
	if (CBondContainer::instance().IsValidIndex(bondIndex))
	{
		const CBondInfo& info = CBondContainer::instance().ElementAtR(bondIndex);
		bondP.m_strCombKey = qb::base::string_format("%s", info.GetCombBondKey());
		if (m_mapCumstomBond.find(bondP.m_strCombKey) == m_mapCumstomBond.end()) {
			m_mapCumstomBond.insert(std::pair<std::string, CNatIRRSingle>(bondP.m_strCombKey, bondP));
			return true;
		}
	}
	return false;
}

void CNatToolsBrokP::DelCumstomBond(const char* cBondKey , const char* cListMarket)
{
	std::string strCombond = qb::base::string_format("%s.%s",cBondKey,cListMarket);
	std::map<std::string,CNatIRRSingle>::const_iterator itr = m_mapCumstomBond.find(strCombond);
	if(itr!= m_mapCumstomBond.end()){
		m_mapCumstomBond.erase(itr);
	}
}

CNatDebtCalCache& CNatDebtCalCache::GetInstance()
{
	static CNatDebtCalCache m_NatDebtCalCache;
	return m_NatDebtCalCache;
}

void CNatDebtCalCache::Clear()
{
	time_t tCur = CSSVContainer::GetServerTime();
	int nDate = (int)qb::base::IntDate::timeToInt(tCur);
	if (m_nCacheDate != nDate){
		m_setPrice.clear();
		//m_mapPrice.clear();
		m_nCacheDate = nDate;
	}
}

void CNatDebtCalCache::AddPrice(CNatDebtCalPrice& price)
{
	m_setPrice.insert(price);
	//m_mapPrice.insert(make_pair(price, 0));
}

bool CNatDebtCalCache::GetPrice(CNatDebtCalPrice& price)
{
	std::set<CNatDebtCalPrice>::const_iterator itr = m_setPrice.find(price);
	if (itr != m_setPrice.end()){
		price = *itr;
		return true;
	}
	//if (m_setPrice.find(price) != m_setPrice.end()){
	//	price = m_setPrice[price];
	//	return true;
	//}
	return false;
}

CNatDebtCalCache::CNatDebtCalCache() : m_nCacheDate(0)
{
	Clear();
}
